/// <reference path="../lib/gd3d_jsloader.d.ts"/>
/// <reference path="../lib/gd3d_render.d.ts"/>

window.onload = () =>
{
    //gd3d.jsLoader.instance().addImportScript("lib/gd3d_io.js");
    gd3d.jsLoader.instance().addImportScript("lib/gd3d_render.js");
    gd3d.jsLoader.instance().preload(() =>
    {
        var app = new App();
        app.init();
        setInterval(() =>
        {
            app.update();
        }, 20);
    }
    );
}

class App
{
    vscode: string = "\
    attribute vec4 _glesVertex;   \
    attribute vec4 _glesColor;                  \
    attribute vec4 _glesMultiTexCoord0;         \
    uniform highp mat4 glstate_matrix_mvp;      \
    varying lowp vec4 xlv_COLOR;                \
    varying highp vec2 xlv_TEXCOORD0;           \
    void main()                                     \
    {                                               \
        highp vec4 tmpvar_1;                        \
        tmpvar_1.w = 1.0;                           \
        tmpvar_1.xyz = _glesVertex.xyz;             \
        xlv_COLOR = _glesColor;                     \
        xlv_TEXCOORD0 = _glesMultiTexCoord0.xy;     \
        gl_Position = (glstate_matrix_mvp * tmpvar_1);  \
    }";

    fscode: string = "         \
    uniform sampler2D _MainTex;                                                 \
    varying lowp vec4 xlv_COLOR;                                                 \
    varying highp vec2 xlv_TEXCOORD0;   \
    void main() \
    {\
        lowp vec4 col_1;    \
        mediump vec4 prev_2;\
        lowp vec4 tmpvar_3;\
        tmpvar_3 = (xlv_COLOR * texture2D(_MainTex, xlv_TEXCOORD0));\
        prev_2 = tmpvar_3;\
        mediump vec4 tmpvar_4;\
        tmpvar_4 = mix(vec4(1.0, 1.0, 1.0, 1.0), prev_2, prev_2.wwww);\
        col_1 = tmpvar_4;\
        gl_FragData[0] = col_1;\
    }\
    ";
    vscode_0: string = "\
    attribute vec4 _glesVertex; \n\
    uniform highp mat4 glstate_matrix_mvp;      \
    void main()\n                                     \
    { \n\
        vec4 v1=_glesVertex;\n\
        v1.w =1.0;\n\
        gl_Position = glstate_matrix_mvp * v1; \n \
    }   \n \
                        ";
    fscode_0: string = "\
    precision mediump float;\n\
    void main()\n  \
    {\n\
        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); \n\
    }\n\
    ";
    init()
    {
        //append canvas
        var canvas = document.createElement("canvas");
        canvas.className = "full";
        canvas.style.position = "absolute";
        canvas.style.width = "98%";
        canvas.style.height = "98%";
        canvas.style.backgroundColor = "#f0f";
        document.body.appendChild(canvas);

        document.body.style.msUserSelect = "none";
        document.body.style.webkitUserSelect = "none";
        var tex = document.createElement("span");
        tex.style.position = "absolute";
        tex.style.width = "98%";
        tex.style.height = "98%";
        tex.textContent = "这是render层的基本绘制测试";
        document.body.appendChild(tex);
        //init webgl;
        this.webgl = <WebGLRenderingContext>canvas.getContext('webgl') ||
            <WebGLRenderingContext>canvas.getContext("experimental-webgl");

        console.log("init webgl done.");
        //gen mesh
        var dat = gd3d.render.meshData.genBoxCCW(0.25);
        //upto glmesh
        var vf = gd3d.render.VertexFormatMask.Position | gd3d.render.VertexFormatMask.Normal | gd3d.render.VertexFormatMask.Color | gd3d.render.VertexFormatMask.UV0;
        var v32 = dat.genVertexDataArray(vf);
        this.mesh = new gd3d.render.glMesh();
        this.mesh.initBuffer(this.webgl, vf, dat.pos.length);
        this.mesh.uploadVertexSubData(this.webgl, v32);
        //0 号 index
        var i16 = dat.genIndexDataArray();
        this.mesh.addIndex(this.webgl, i16.length);
        this.mesh.uploadIndexSubData(this.webgl, 0, i16);

        //1 号 index tri 2 line
        var i16line = dat.genIndexDataArrayTri2Line();
        this.mesh.addIndex(this.webgl, i16line.length);
        this.mesh.uploadIndexSubData(this.webgl, 1, i16line);

        //set mat
        var shaderres = new gd3d.render.shaderPool();
        shaderres.compileVS(this.webgl, "def", this.vscode);
        shaderres.compileFS(this.webgl, "def", this.fscode);
        this.program = shaderres.linkProgram(this.webgl, "def", "def");
        shaderres.compileVS(this.webgl, "def0", this.vscode_0);
        shaderres.compileFS(this.webgl, "def0", this.fscode_0);
        this.program0 = shaderres.linkProgram(this.webgl, "def0", "def0");

        var texture = new gd3d.render.glTexture2D(this.webgl);
        var img = new Image();
        img.onload = () =>
        {
            texture.uploadImage(img, true, true);
        }
        img.src = "test/render_01/zg03.png";
        this.matrix = new gd3d.math.matrix();

        this.pass2 = new gd3d.render.glDrawPass();
        this.pass2.setProgram(this.program0);
        this.pass2.state_showface = gd3d.render.ShowFaceStateEnum.ALL;

        this.pass = new gd3d.render.glDrawPass();
        this.pass.setProgram(this.program);
        this.pass.uniformTexture("_MainTex", texture);
        //this.pass.drawbegin = 9;
        //this.pass.drawcount = 24;
        this.pass.state_showface = gd3d.render.ShowFaceStateEnum.ALL;

    }
    webgl: WebGLRenderingContext;
    mesh: gd3d.render.glMesh;
    program: gd3d.render.glProgram;
    program0: gd3d.render.glProgram;
    matrix: gd3d.math.matrix;

    pass: gd3d.render.glDrawPass;

    pass2: gd3d.render.glDrawPass;
    timer: number = 0;
    update()
    {
        if (this.webgl.canvas.clientWidth != this.webgl.canvas.width || this.webgl.canvas.clientHeight != this.webgl.canvas.height)
        {
            this.webgl.canvas.width = this.webgl.canvas.clientWidth;
            this.webgl.canvas.height = this.webgl.canvas.clientWidth;

        }
        var width = this.webgl.canvas.width;
        var height = this.webgl.canvas.height;

        this.webgl.clearColor(0.1, 0.5, 0.5, 1);
        this.webgl.clear(this.webgl.COLOR_BUFFER_BIT | this.webgl.DEPTH_BUFFER_BIT);
        //viewport 管不到clear
        this.webgl.viewport(0.1 * width, 0.1 * height, width * 0.8, height * 0.8);

        this.timer += 0.05;
        gd3d.math.matrixMakeRotateAxisAngle(new gd3d.math.vector3(0, 1, 0), this.timer % (Math.PI * 2), this.matrix);
        var rot2 = new gd3d.math.matrix();
        gd3d.math.matrixMakeRotateAxisAngle(new gd3d.math.vector3(1, 0, 0), -0.3, rot2);
        gd3d.math.matrixMultiply(rot2, this.matrix, this.matrix);
        //绘制
        {
            ////这一堆加起来，是一个pass的概念
            //this.webgl.disable(this.webgl.CULL_FACE);//cull
            //this.webgl.depthMask(false);//这是zwrite
            //this.webgl.disable(this.webgl.DEPTH_TEST);//这是ztest
            //this.webgl.disable(this.webgl.BLEND);//alphablend


            ////use program
            //this.program.use(this.webgl);
            ////bind attribute &vbo

            ////set uniform
            //this.webgl.uniformMatrix4fv(this.program.mapUniform["glstate_matrix_mvp"].location, false, this.matrix.rawData);

            ////this.webgl.uniform1i(this.program.mapUniform["_MainTex"].location, 0);
            ////render
            //this.mesh.bind(this.webgl, this.program);
            //this.mesh.drawElementTris(this.webgl);
            this.pass.uniformMatrix("glstate_matrix_mvp", this.matrix);
            this.pass.draw(this.webgl, this.mesh);

            this.pass2.uniformMatrix("glstate_matrix_mvp", this.matrix);
            this.pass2.draw(this.webgl, this.mesh, gd3d.render.DrawModeEnum.EboLine, 1);
        }
        this.webgl.flush();
    }
}